lpunbfandomcom-20200214-history
Seminario LUA - 1/2014 (Lucas, Henrique, Miguel)
Histórico A linguagem de programação Lua é inteiramente projetada, implementada e desenvolvida no Brasil, por uma equipe na PUC-Rio (Pontifícia Universidade Católica do Rio de Janeiro), onde nasceu e cresceu. Lua foi criada lá em 1993 por Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes, membros da Computer Graphics Technology Group, grupo da universidade mais conhecido como Tecgraf. Versões da Lua antes da versão 5.0 foram liberadas sob uma licença similar à licença BSD. A partir da versão 5.0, Lua foi licenciada sob a licença MIT. Atualmente, Lua é desenvolvida no laboratório LabLua do Departamento de Informática da PUC-Rio. Alguns de seus parentes mais próximos são o Icon para sua concepção e Python para a sua facilidade de utilização por não-programadores. Em um artigo publicado no Dr. Dobb's Journal, os criadores da Lua também afirmam que Lisp e Scheme foram uma grande influência na decisão de desenvolver o quadro como a principal estrutura de dados de Lua. Lua tem sido usada em várias aplicações, tanto comerciais como não-comerciais. fonte: http://www.vivaolinux.com.br/artigo/Introducao-a-LUA-uma-poderosa-linguagem-de-programacao Características Lua é uma linguagem robusta Lua é usada em muitas aplicações industriais (e.g., Adobe's Photoshop Lightroom), com ênfase em sistemas embutidos (e.g., o middleware Ginga para TV digital) e jogos (e.g., World of Warcraft). Lua é atualmente a linguagem de script mais usada em jogos. Lua tem um sólido manual de referência e existem vários livros sobre a linguagem. Várias versões de Lua foram lançadas e usadas em aplicações reais desde a sua criação em 1993. Lua é rápida Lua tem uma merecida reputação de ótimo desempenho. Outras linguagens de script aspiram ser "tão rápidas quanto Lua". Vários benchmarks mostram Lua como a linguagem mais rápida dentre as linguagens de script interpretadas. Lua é rápida não só em programas específicos para benchmarks, mas no dia-a-dia também. Porções substanciais de aplicações grandes são escritas em Lua. Lua é portátil Lua é distribuída via um pequeno pacote e compila sem modificações em todas as plataformas que têm um compilador ANSI/ISO C. Lua roda em todos os tipos de Unix e Windows, e também em dispositivos móveis (como computadores de mão e celulares que usam BREW, Symbian, Pocket PC, etc.) e em microprocessadores embutidos (como ARM e Rabbit) para aplicações como Lego MindStorms. Lua é embutível Lua é uma engine rápida e pequena que você pode facilmente embutir na sua aplicação. Lua tem uma API simples e bem documentada que permite uma integração forte com código escrito em outras linguagens. É simples estender Lua com bibliotecas escritas em outras linguagens. Também é simples estender programas escritos em outras linguagens com Lua. Lua é usada para estender programas escritos não só em C e C , mas também em Java, C#, Smalltalk, Fortran, Ada, Erlang, e mesmo outras linguagens de script, como Perl and Ruby. Lua é poderosa e simples Um conceito fundamental no projeto de Lua é fornecer meta-mecanismos para a implementação de construções, em vez de fornecer uma multidão de construções diretamente na linguagem. Por exemplo, embora Lua não seja uma linguagem puramente orientada a objetos, ela fornece meta-mecanismos para a implementação de classes e herança. Os meta-mecanismos de Lua trazem uma economia de conceitos e mantêm a linguagem pequena, ao mesmo tempo que permitem que a semântica seja estendida de maneiras não convencionais. Lua é pequena Incluir Lua numa aplicação não aumenta quase nada o seu tamanho. O pacote de Lua 5.1.4, contendo o código fonte, documentação e exemplos, ocupa 212K comprimido e 860K descompactado. O fonte contém cerca de 17000 linhas de C. No Linux, o interpretador Lua contendo todas as bibliotecas padrões de Lua ocupa 153K e a biblioteca Lua ocupa 203K. Lua é livre Lua é software livre de código aberto, distribuída sob uma licença muito liberal (a conhecida licença MIT). Lua pode ser usada para quaisquer propósitos, incluindo propósitos comerciais, sem qualquer custo ou burocracia. Basta fazer um download e usá-la. Lua tem importância global O projeto e a evolução de Lua foram apresentados em junho de 2007 na HOPL III, a 3a Conferência da ACM sobre a História das Linguagens de Programação. Essa conferência ocorre a cada 15 anos (a primeira foi em 1978 e a segunda em 1993) e somente poucas linguagens são apresentadas a cada vez. A escolha de Lua para a HOPL III é um importante reconhecimento do seu impacto mundial. Lua é a única linguagem de programação de impacto desenvolvida fora do primeiro mundo, estando atualmente entre as 20 linguagens mais populares na Internet (segundo o índice TIOBE). Premissas A linguagem Lua não tem premissas pré-definidas, mas considerando o seu contexto de criação, podemos dizer que as duas principais premissas e pré-requisitos de Lua é evitar sintaxe e semântica difíceis ou complexas, e ser altamente portátil. Isso pelo fato de que na sua criação, o seu propósito inicial era atender aos usuários inexperientes e não profissionais da linguagem, que eram os empregados da empresa Petrobras, além da diversidade de sistemas e plataformas computacionais. Domínio de Aplicação Como a linguagem foi criada para ser rápida, eficiente e simples, o seu domínio de aplicação passou a ser qualquer programador em fase inicial ou avançada, além do grande uso na área de desenvolvimento de jogos (como Angry Birds, Far Cry, Tibia, dentre outros), e também a embarcação em softwares complexos, cujo este era o propósito inicial da linguagem, incluindo automação e configuração e processamento de texto. Usuário Caracterísito O usuário característico de Lua são todos os programadores profissionais ou não, quer por curiosidade, obrigação ou livre escolha, optaram por utilizar a linguagem. Além desses, há um grande número de usuários na área já relatada acima na seção de domínio de aplicação, como desenvolvedores de jogos e de sistemas complexos. fonte: http://www.oficinadanet.com.br/artigo/programacao/a_linguagem_de_programacao_lua_-_parte_1 Sintaxe e Semântica Lua é uma linguagem de formato livre. Ela ignora espaços (incluindo quebras de linha) e comentários entre elementos léxicos (tokens), exceto como delimitadores entre nomes e palavras-chave. Nomes (também chamados de identificadores) em Lua podem ser qualquer cadeia de letras, dígitos, e sublinhados, que não iniciam com um dígito. Identificadores são usados para nomear variáveis, campos de tabelas, e rótulos. As seguintes palavras-chave são reservadas e não podem ser usadas como nomes: and break do else elseif end false for function goto if in local nil not or repeat return then true until while Lua é uma linguagem que diferencia minúsculas de maiúsculas. 1-)Tipos de Dados e Variáveis Lua é uma linguagem dinamicamente tipada. Isso significa que variáveis não possuem tipos; somente valores possuem tipos. Não há definições de tipo na linguagem. Todos os valores carregam o seu próprio tipo. Há oito tipos básicos em Lua: nil, boolean, number, string, function, userdata, thread, e table. Nil é o tipo do valor nil, cuja propriedade principal é ser diferente de qualquer outro valor; ele geralmente representa a ausência de um valor útil. Boolean é o tipo dos valores false e true. Tanto nil como false tornam uma condição falsa; qualquer outro valor a torna verdadeira. Number representa tanto números inteiros como números reais (ponto flutuante de precisão dupla). String representa sequências imutáveis de bytes. Lua é 8 bits pura: cadeias podem conter qualquer valor de 8 bits, incluindo zeros ('\0') dentro delas. Lua pode chamar (e manipular) funções escritas em Lua e funções escritas em C. O tipo userdata é oferecido para permitir que dados C arbitrários sejam guardados em variáveis Lua. Um valor userdata é um ponteiro para um bloco de memória bruta. Há dois tipos de userdata: userdata completo, onde o bloco de memória é gerenciado por Lua, e userdata leve, onde o bloco de memória é gerenciado pelo hospedeiro. Userdata não possui operações pré-definidas em Lua, exceto atribuição e teste de identidade. Através do uso de metatabelas, o programador pode definir operações para valores userdata completos. Valores userdata não podem ser criados ou modificados em Lua, somente através da API C. Isso garante a integridade de dados que pertencem ao programa hospedeiro. O tipo thread representa fluxos de execução independentes e é usado para implementar co-rotinas. Não confunda fluxos de execução Lua com processos leves do sistema operacional. Lua dá suporte a co-rotinas em todos os sistemas, até mesmo naqueles que não dão suporte a processos leves. O tipo table implementa arrays associativos, isto é, arrays que podem ser indexados não apenas com números, mas com qualquer valor Lua exceto nil e NaN (Not a Number, um valor numérico especial usado para representar resultados indefinidos ou não representáveis, tais como 0/0). Tabelas podem ser heterogêneas; isto é, elas podem conter valores de todos os tipos (exceto nil). Qualquer chave com valor nil não é considerada parte da tabela. De modo recíproco, qualquer chave que não é parte da tabela possui um valor nil'''associado. Tabelas são o único mecanismo de estruturação de dados em Lua; elas podem ser usadas para representar arrays comuns, sequências, tabelas de símbolos, conjuntos, registros, grafos, árvores, etc. Para representar registros, Lua usa o nome do campo como um índice. A linguagem dá suporte a essa representação fornecendo a.nome como açúcar sintático para a"nome". Há várias maneiras convenientes para criar tabelas em Lua. Usamos o termo sequência para denotar uma tabela onde o conjunto de todas as chaves numéricas positivas é igual a {1..} para algum inteiro n, que é chamado o comprimento da sequência. Assim como os índices, os valores dos campos de uma tabela podem ser de qualquer tipo. Em particular, por causa que funções são valores de primeira classe, campos de tabela podem conter funções. Portanto, tabelas podem também conter métodos. A indexação de tabelas segue a definição de igualdade primitiva na linguagem. As expressões ai e aj denotam o mesmo elemento da tabela se e somente se i e j são iguais primitivos (isto é, iguais sem metamétodos). Valores do tipo table, function, thread, e userdata (completo) são objetos: variáveis não contêm realmente esses valores, somente referências para eles. Atribuição, passagem de parâmetro, e retornos de função sempre manipulam referências para tais valores; essas operações não implicam em qualquer espécie de cópia. Há três tipos de variáveis em Lua: variáveis globais, variáveis locais, e campos de tabelas. Um único nome pode denotar uma variável global ou uma variável local (ou um parâmetro formal de uma função, que é um tipo particular de variável local). Qualquer nome de variável é assumido ser global a menos que explicitamente declarado como um local. Variáveis locais possuem escopo léxico: variáveis locais podem ser acessadas livremente por funções definidas dentro do seu escopo. Antes da primeira atribuição a uma variável, seu valor é '''nil. 2-)Comandos Um bloco é uma lista de comandos, que são executados sequencialmente. A unidade de compilação de Lua é chamada de um trecho. Sintaticamente, um trecho é simplesmente um bloco. Lua trata um trecho como o corpo de uma função anônima com um número variável de argumentos. Dessa forma, trechos podem definir variáveis locais, receber argumentos, e retornar valores. 2.1)Atribuição Lua permite atribuições múltiplas. Por isso, a sintaxe para atribuição define uma lista de variáveis no lado esquerdo e uma lista de expressões no lado direito. Antes da atribuição, a lista de valores é ajustada para o comprimento da lista de variáveis. Se há mais valores do que o necessário, os valores em excesso são descartados. Se há menos valores do que o necessário a lista é estendida com tantos nil's quantos sejam necessários. Se a lista de expressões termina com uma chamada de função, então todos os valores retornados por essa chamada entram na lista de valores, antes do ajuste (exceto quando a chamada é delimitada por parênteses) O comando de atribuição primeiro avalia todas as suas expressões e somente então as atribuições são realizadas. Assim o código i = 3 i, ai = i+1, 20 atribui 20 a a3, sem afetar a4 porque o i em ai é avaliado (como 3) antes de receber 4. Similarmente, a linha x, y = y, x troca os valores de x e y, e x, y, z = y, z, x permuta de maneira cíclica os valores de x, y, e z. 2.2)Estruturas de Controle As estruturas de controle if, while, e repeat for '''possuem o significado usual e a sintaxe familiar. A expressão da condição de uma estrutura de controle pode retornar qualquer valor. Tanto '''false quanto nil são considerados falso. Todos os valores diferentes de nil e false são considerados verdadeiro (em particular, o número 0 e a cadeia vazia são também verdadeiro). No laço repeat–'until', o bloco interno não termina na palavra chave until, mas somente após a condição. Assim, a condição pode se referir a variáveis locais declaradas dentro do corpo do laço. O comando goto transfere o controle do programa para um rótulo. Um rótulo é visível em todo o bloco onde ele é definido, exceto dentro de blocos aninhados onde um rótulo com o mesmo nome é definido e dentro de funções aninhadas. Um goto pode fazer um desvio para qualquer rótulo visível desde que ele não entre no escopo de uma variável local. Rótulos e comandos vazios são chamados de comandos nulos, uma vez que eles não realizam ações. O comando break termina a execução de um laço while, repeat, ou for, fazendo um desvio para o próximo comando após o laço.Um break termina o laço mais interno. O comando return é usado para retornar valores de uma função ou de um trecho (que é uma função disfarçada). Funções podem retornar mais do que um valor. O comando return pode somente ser escrito como o último comando de um bloco. Se for realmente necessário um return no meio de um bloco, então um bloco interno explícito pode ser usado, como na expressão idiomática do return end, porque agora return é o último comando de seu bloco (interno). 2.3)Operadores (em ordem de precedência): A precedência dos operadores em Lua segue a tabela a seguir, da menor prioridade para a maior: or and < > <= >= ~= .. + - * / % not # - (unário) ^ 2.4)Funções Uma definição de função é uma expressão executável, cujo valor tem tipo function. Quando Lua pré-compila um trecho, todos os corpos de funções do trecho são pré-compilados também. Então, sempre que Lua executa a definição de uma função, a função é instanciada (ou fechada). Essa instância de função (ou fecho) é o valor final da expressão. Quando uma função é chamada, a lista de argumentos é ajustada para o comprimento da lista de parâmetros, a menos que a função seja uma função vararg, a qual é indicada por três pontos ('...') no fim de sua lista de parâmetros. Uma função vararg não ajusta sua lista de argumentos; ao invés disso, ela coleta todos os argumentos extras e os fornece à função através de uma expressão vararg, que também é denotada por três pontos. O valor desta expressão é uma lista de todos os argumentos extras de fato, similar a uma função com múltiplos resultados. Se uma expressão vararg é usada dentro de outra expressão ou no meio de uma lista de expressões, então sua lista de retorno é ajustada para um elemento. Se a expressão é usada como o último elemento de uma lista de expressões, então nenhum ajuste é feito (a menos que a última expressão esteja entre parênteses). Como um exemplo, considere as seguintes definições: function f(a, b) end function g(a, b, ...) end function r() return 1,2,3 end Em seguida, temos o seguinte mapeamento de argumentos para parâmetros e para expressões vararg: CHAMADA PARÂMETROS f(3) a=3, b=nil f(3, 4) a=3, b=4 f(3, 4, 5) a=3, b=4 f(r(), 10) a=1, b=10 f(r()) a=1, b=2 g(3) a=3, b=nil, ... --> (nada) g(3, 4) a=3, b=4, ... --> (nada) g(3, 4, 5, 8) a=3, b=4, ... --> 5 8 g(5, r()) a=5, b=1, ... --> 2 3 Resultados são retornados usando o comando return. Se o controle alcança o fim de uma função sem encontrar um comando return, então a função retorna sem nenhum resultado. Exemplos de Programas 1-) Algoritmo de Markov (gerador de 'texto randômico)' -- Markov Chain Program in Lua function allwords () local line = io.read() -- current line local pos = 1 -- current position in the line return function () -- iterator function while line do -- repeat while there are lines local s, e = string.find(line, "%w+", pos) if s then -- found a word? pos = e + 1 -- update next position return string.sub(line, s, e) -- return the word else line = io.read() -- word not found; try next line pos = 1 -- restart from first position end end return nil -- no more lines: end of traversal end end function prefix (w1, w2) return w1 .. ' ' .. w2 end local statetab function insert (index, value) if not statetabindex then statetabindex = {n=0} end table.insert(statetabindex, value) end local N = 2 local MAXGEN = 10000 local NOWORD = "\n" -- build table statetab = {} local w1, w2 = NOWORD, NOWORD for w in allwords() do insert(prefix(w1, w2), w) w1 = w2; w2 = w; end insert(prefix(w1, w2), NOWORD) -- generate text w1 = NOWORD; w2 = NOWORD -- reinitialize for i=1,MAXGEN do local list = statetabw2) -- choose a random item from list local r = math.random(table.getn(list)) local nextword = listr if nextword NOWORD then return end io.write(nextword, " ") w1 = w2; w2 = nextword end 2-) Programa para percorrer o texto de um arquivo function allwords () local line = io.read() -- current line local pos = 1 -- current position in the line return function () -- iterator function while line do -- repeat while there are lines local s, e = string.find(line, "%w+", pos) if s then -- found a word? pos = e + 1 -- next position is after this word return string.sub(line, s, e) -- return the word else line = io.read() -- word not found; try next line pos = 1 -- restart from first position end end return nil -- no more lines: end of traversal end end -- use example for word in allwords() do print(word) end 3-) Gerador de permutações de elementos function permgen(a,n) if n 0 then coroutine.yield(a) else for i=1,n do -- put i-th element as the last one an, ai = ai, an -- generate all permutations of the other elements permgen(a, n - 1) -- restore i-th element an, ai = ai, an end end end function perm (a) local n = table.getn(a) return coroutine.wrap(function () permgen(a, n) end) end function printResult (a) for i,v in ipairs(a) do io.write(v, " ") end io.write("\n") end for p in perm{"a", "b", "c"} do printResult(p) end Fonte: www.lua.org Critérios de Avaliação da Linguagem 1-) Legibilidade É uma linguagem de difícil legibilidade. Possui blocos e estrutura de controle bem definidos, porém pode realizar múltiplas atribuições e retornos, fazendo com que seja difícil ao programador identifica-las muitas vezes. a,b,c = x, f() -- f() é ajustado para 2 resultados a,b,c = f() -- f() é ajustado para 3 resultados Com relação a ortogonalidade, LUA é dinamicamente tipada, isso é, não existe declaração de variáveis, o que é ruim para a verificação e correção de erros. Como sua estrutura de dados é feito por tabelas - vetores, matrizes, etc., devem ser implementados com o uso de tabelas - é uma linguagem de sintaxe simples porém reduz sua legibilidade. Tabela como estrutura: f = { x = 10, y = 20 } -- Cria nova tabela print(f"x") -- Imprime 10 Tabela como vetor: f = { "a", "b", "c", "d" } print(f2) -- Imprime "b". Lua começa no índice 1 2-)Capacidade de Escrita Sua capacidade de escrita é boa, possui uma boa simplicidade global devido sua estrutura de dados feito por tabelas, o que torna LUA uma linguagem de fácil aprendizagem. Uma característica essencial de Lua é a semântica Extensível, ou seja, um pequeno conjunto de características gerais que podem ser estendidas para encaixar diferentes tipos de problemas. Lua, por exemplo, não contém apoio explícito à herança, mas permite que ela seja executada com relativa facilidade com metatables. Lua também permite que programadores quando implementam nomes, classes, e outras funções, empreguem técnicas de programação funcional e completos escopos lexicais. O exemplo a seguir mostra uma tabela “infinita”. Para qualquer valor “n”, “fibs n” dará o enésimo número Fibonacci usando programação dinâmica. Usamos a função setmetatable() para fazer uma tabela agir como uma meta-tabela para um determinado objeto fibs = { 1, 1 } ''-- Valores iniciais de fibs1 e fibs2.'' setmetatable(fibs, { ''-- faz uma tabela agir como uma meta-tabela'' __index = function(name, n) ''-- Função chamada se fibsn não existir'' namen = name- 1 + name- 2 ''-- Calcula e grava fibsn.'' return namen end }) 3-)Confiabilidade Devido a sua verificação de tipos dinâmica e sua baixa legibilidade, é uma linguagem não muito confiável. Apesar disso, há uma função em sua biblioteca destinada ao tratamento de exceções (lua_pcall, error) e toda vez que ocorre um erro durante a compilação ou execução, o controle retorna para C (suas ações começam em C no programa hospedeiro), que toma medidas para o erro. 4-)Custo Seu custo de treinamento é baixo devido a sua simples sintaxe e por ser um software livre. Porém seu custo de manutenção é alto devido a sua baixa legibilidade. 5-)Portabilidade LUA usa como compilação o padrão ANSI (ISO) C. Dessa forma, não é necessário a adaptação a um novo ambiente, na maioria dos casos, o que torna a linguagem uma das mais portáteis existentes. Por ser uma linguagem de extensão, Lua não possui a noção de um programa "principal": ela somente funciona embarcada em um cliente hospedeiro, chamado de programa embarcante ou simplesmente de hospedeiro. O programa hospedeiro pode invocar funções para executar um pedaço de código Lua, pode escrever e ler variáveis Lua, e pode registrar funções C para serem chamadas por código Lua. Através do uso de funções C, Lua pode ser aumentada para lidar com uma variedade ampla de domínios diferentes, criando assim linguagens de programação personalizadas que compartilham um arcabouço sintático